package com.sq.partner.manager.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.sq.partner.manager.common.exception.AppException;
import com.sq.partner.manager.dao.DictManagerDao;
import com.sq.partner.manager.dao.SchoolConfigDao;
import com.sq.partner.manager.mybatis.model.DictDto;
import com.sq.partner.manager.mybatis.model.GatewayUser;
import com.sq.partner.manager.service.SchoolConfigService;
import com.sq.partner.manager.util.ExcelUtil;
import com.sq.partner.manager.util.LogUtil;
import com.sq.partner.manager.util.StrUtil;
import com.sq.partner.manager.util.excel.ExcelEntity;
import com.sq.partner.manager.util.excel.ExportExcelBuilderTool;

@Service
public class SchoolConfigServiceImpl implements SchoolConfigService {
	private static Logger logger = LogUtil.getLog(SchoolConfigServiceImpl.class);
	
	@Resource
	DictManagerDao dictManagerDao;
	@Resource
	SchoolConfigDao schoolConfigDao;
	@Resource
	ExportExcelBuilderTool exportExcelBuilderTool;
	
	@Override
	public List<InputStream> getFileInputStream(MultipartFile[] myfiles)
			throws AppException {
		List<InputStream> inputStreams=new ArrayList<InputStream>();
		try {
			for(MultipartFile file : myfiles){
				String fileNameStr = file.getOriginalFilename();
				int lastDotIndex = fileNameStr.lastIndexOf(".");
				if(-1==lastDotIndex){
					throw new AppException("请选择扩展名为 .xls 的文件上传");
				}else{
					String extName = fileNameStr.substring(lastDotIndex+1,fileNameStr.length());
					if(!"xls".equals(extName.toLowerCase())){
						throw new AppException("请选择扩展名为 .xls 的文件上传");
					}
				}
				if (file.isEmpty()) {
					throw new AppException("上传失败，上传文件不能为空！");
				} else {
					InputStream inputStream = file.getInputStream();
					inputStreams.add(inputStream);
				}
			}
		} catch (IOException e) {
			logger.info("上传错误!请稍后重试",e);
			throw new AppException("上传错误!请稍后重试");
		}
		return inputStreams;
	}

	@Override
	public void insertDataToDB(InputStream inputStream, GatewayUser user,HttpSession session) throws Exception {
		HSSFWorkbook workBook = null;
		int errorCount = 0;
		StringBuffer errorMsg = new StringBuffer();
		StringBuffer errorMsg2 = new StringBuffer();
		int lastRow = 0;
		List<DictDto> allList = new ArrayList<DictDto>();
		List<DictDto> schoolList = new ArrayList<DictDto>();
		List<DictDto> gradeList = new ArrayList<DictDto>();
		try {
			workBook = new HSSFWorkbook(inputStream);
		} catch (Exception e) {
			logger.info("上传失败，上传文件内容有误", e);
			throw new AppException("上传失败，上传文件内容有误!");
		}
		HSSFSheet sheet = workBook.getSheetAt(0);
		if (sheet != null) {
			lastRow = sheet.getLastRowNum();
		}
		if (lastRow > 0 && null!=sheet) {
			int count = sheet.getLastRowNum();
			Map<String, Object> map = new HashMap<String, Object>();
			//select * from t_gateway_dict t where t.code_type = 'school_config'  全量查
			List<Map<String, Object>> schoolMap = schoolConfigDao.querySchoolConfigSelect(map);
			List<DictDto> dictList = new ArrayList<DictDto>();
			for (Map<String, Object> schoolInfoMap : schoolMap) {
				//循环学校配置字典|new 新的dict对象 
				DictDto dictDto = new DictDto();
				dictDto.setCode(schoolInfoMap.get("CODE").toString());
				dictDto.setCodeType("school_config");
				if (schoolInfoMap.get("PARENT_CODE")!=null) {
					dictDto.setParentCode(schoolInfoMap.get("PARENT_CODE").toString());
				}
				//将已存在的dict 对象，全都复制到dictList中
				dictList.add(dictDto);
			}
			
			Map<String,String> deptMap = new HashMap<String, String>();
			for (int rowNum = 1; rowNum <= count; rowNum++) {
				HSSFRow hssfRow = sheet.getRow(rowNum);
				if (hssfRow != null) {
					for (int colNum = 0; colNum < hssfRow.getLastCellNum(); colNum++) {
						if (StrUtil.isEmpty(ExcelUtil.getCellText(hssfRow.getCell(colNum)).trim())) {
							errorMsg.append("第" + (rowNum + 1)+ " 行数据未导入，原因：列数据为必录项不允许为空，请检查 <br>");
							errorCount++;
							continue;
						}
					}
					if (errorCount > 10) {
						throw new AppException("上传失败:<br>" + errorMsg.toString());
					}
					String dptNo = ExcelUtil.getCellText(hssfRow.getCell(0)).trim();
					deptMap.put(dptNo, "");
					String schoolDesc = ExcelUtil.getCellText(hssfRow.getCell(1)).trim();
					String schoolName = ExcelUtil.getCellText(hssfRow.getCell(2)).trim();
					String schoolGrade = ExcelUtil.getCellText(hssfRow.getCell(3)).trim();
					String schoolClass = ExcelUtil.getCellText(hssfRow.getCell(4)).trim();
					
					DictDto dictDto = new DictDto();
					dictDto.setCodeType("school_config");
					dictDto.setCode(dptNo);
					dictDto.setCodeName(schoolName);
					dictDto.setCodeDesc(schoolDesc);
					dictDto.setOtherCode(schoolGrade);
					dictDto.setOtherCode2(schoolClass);
					dictDto.setStatus("1");
					allList.add(dictDto);
					
					
					
				}
			}
			
			if (dictList!=null&&dictList.size()>0) {
				//delete from t_gateway_dict where code_type = 'school_config' and code like #{value}||'%'
				//删除机构下所有信息
				for(String deptNo : deptMap.keySet()){
					if(deptNo.length() == 8 ){
						dictManagerDao.deleteGatewayDictByDeptNo(deptNo);
					}
				}
				
			}
			sort(allList);
			schoolList = getSchoolList(allList);
			gradeList = getGradeList(allList,schoolList);
			
			if (StrUtil.isNotEmpty(errorMsg.toString())) {
				throw new AppException("上传失败:<br>" + errorMsg.toString());
			}
		} else{
			errorMsg.append("Excel内容为空 <br>");
			throw new AppException("上传失败:<br>" + errorMsg.toString());
		}
		if (schoolList.size()> 0) {
			for (int i = 0; i < schoolList.size(); i++) {
				dictManagerDao.insertGatewayDict(schoolList.get(i));
			}
		}
		if (gradeList.size()> 0) {
			for (int i = 0; i < gradeList.size(); i++) {
				dictManagerDao.insertGatewayDict(gradeList.get(i));
			}
		}
		if (StrUtil.isNotEmpty(errorMsg2.toString())) {
			throw new AppException("上传完毕:<br>" + errorMsg2.toString());
		}else{
			session.setAttribute("result", "学校信息配置导入成功");
		}
	} 
	
	//去重学校名称和出单机构代码
	private List<DictDto> getSchoolList(List<DictDto> allList) {
		List<DictDto> list = new ArrayList<DictDto>(allList);
		List<DictDto> schoolList = new ArrayList<DictDto>();
		String dptNo = "";
		String UpEn = "A";
		Map<String,String> map = new HashMap<String, String>();
		List<DictDto> newList = new ArrayList<DictDto>();
		//重新编写去重逻辑
		for (int i = 0; i < list.size() - 1; i++) {
			if(map.get(list.get(i).getCode() + list.get(i).getCodeName()) == null){
				map.put(list.get(i).getCode() + list.get(i).getCodeName(), "true");
				newList.add(list.get(i));
				//logger.info( "|||||" + list.get(i).getCode()+ list.get(i).getCodeName() + "加入到map中" );
			}else {
				//logger.info( "-----" + list.get(i).getCode()+ list.get(i).getCodeName() + "已存在" );
				continue;
			}
		}
		for (DictDto dictDto : newList) {
			DictDto dto = new DictDto();
			dto.setCodeType("school_config");
			if (!dptNo.equals(dictDto.getCode())) {
				UpEn = "A";
				dptNo = dictDto.getCode();
				dto.setCodeName(dictDto.getCodeName());
				dto.setCodeDesc(dictDto.getCodeDesc());
				dto.setCode(dictDto.getCode()+UpEn);
			}else{
				UpEn = getNextUpEn(UpEn);
				dto.setCode(dictDto.getCode()+UpEn);
				dto.setCodeName(dictDto.getCodeName());
				dto.setCodeDesc(dictDto.getCodeDesc());
			}
			schoolList.add(dto);
		}
		return schoolList;
	}

	private List<DictDto> getGradeList(List<DictDto> allList, List<DictDto> schoolList) {
		List<DictDto> gradeList = new ArrayList<DictDto>();
		for (DictDto school : schoolList) {
			int num = 0;
			for (DictDto all : allList) {
				//学校名相同  出单机构相同
				if (school.getCode().substring(0, 8).equals(all.getCode())&&school.getCodeName().equals(all.getCodeName())) {
					DictDto dictDto = new DictDto();
					dictDto.setCodeType("school_config");
					dictDto.setCode(school.getCode()+num);
					num+=1;
					dictDto.setCodeName(all.getOtherCode());
					dictDto.setCodeDesc(all.getOtherCode2());
					dictDto.setParentCode(school.getCode());
					gradeList.add(dictDto);
				}
			}
		}
		for (int i = 0; i < gradeList.size() - 1; i++) {
			for (int j = gradeList.size() - 1; j > i; j--) {
				//父code相同 年级名相同  班级整合
				if (gradeList.get(j).getCodeName().equals(gradeList.get(i).getCodeName())&&gradeList.get(j).getParentCode().equals(gradeList.get(i).getParentCode())) {
					gradeList.get(i).setCodeDesc(gradeList.get(i).getCodeDesc()+","+gradeList.get(j).getCodeDesc());
					gradeList.remove(j);
				}
			}
		}
		return gradeList;
	}
	
	private String getNextUpEn(String en){
		if(en==null || en.equals("")){
			return "A";
		}

	    int lastUpperEnglish = (int)'Z'; 
	    int lastLowerEnglish = (int)'z';
	    char[] c = en.toCharArray();
	    if(c.length>1){
	    	return null;
	    }else{
	    	int now = (int)c[0];//A-Z-> 65-90
	    	//a-z 97-122
	    	if(now == lastUpperEnglish){
	    		return "a";	
	    	}
	    	if(now >= lastLowerEnglish){
	    		return null;
	    	}
	    	char uppercase = (char)(now+1);
	    	return String.valueOf(uppercase);
	    }
	}

	@Override
	public List<Map<String,Object>> demandExportSelect(Map<String, Object> paramMap) throws Exception {
		return schoolConfigDao.queryDictByParameter(paramMap);
	}

	@Override
	public void downloadSchoolConfigFile1(List<Map<String, Object>> demandExportList,
			HttpServletResponse response) throws Exception {
		ExcelEntity excel = new ExcelEntity();
        excel.setResults(demandExportList);
        excel.setFileName("schoolConfig");
        excel.setTitles("出单机构,学校描述,学校名称,年级,班级");
        
        excel.setTitleKeys("CODE,CODE_DESC,CODE_NAME,OTHER_CODE,OTHER_CODE2");
        excel.setColumns("20,20,20,20,20");
        exportExcelBuilderTool.buildExcel(response,excel);
	}

	@Override
	public List<Map<String, Object>> querySchoolConfigSelect(
			Map<String, Object> map) throws Exception {
		return schoolConfigDao.querySchoolConfigSelect(map);
	}

	@Override
	public void updateSchoolConfig(DictDto dict) throws Exception {
		schoolConfigDao.updateSchoolConfig(dict);
	}
    
	
	
	private static void sort(List<DictDto> data) {
		 
        Collections.sort(data, new Comparator<DictDto>() {
 
			@Override
			public int compare(DictDto d1, DictDto d2) {
				Integer a = Integer.parseInt(d1.getCode());
                Integer b = Integer.parseInt(d2.getCode());
                // 升序
                return a.compareTo(b);
			}
        });
    }
	
	/**
	 * 比较两个dictDto对象的code 和 codeName 是否相等
	 * @param d1
	 * @param d2
	 * @return 
	 */
	boolean compareNext(DictDto d1,  DictDto d2){
		if(d1 == null && d2 != null || (d1 != null && d2 == null)){
			return false;
		}
		if(d1.getCode().equals(d2.getCode()) && d1.getCodeName().equals(d2.getCodeName())){
			return true ;
			
		}else {
			return false;
		}
	}
}
